<template>
  <div class="map" style="width: 100%; height: 900px">
    <div class="map-content" v-loading="loading">
      <!-- 地图 -->
      <div :id="mapId" style="width: 100%;height: 100%"></div>
    </div>
  </div>
</template>
<script>
import 'ol/ol.css'
import {Feature, Map, View} from 'ol'
import {Cluster, Vector as VectorSource, WMTS, XYZ} from 'ol/source'
import {GeoJSON} from 'ol/format'
import {bbox} from 'ol/loadingstrategy'
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer'
import {Fill, Icon, Style} from 'ol/style'
import proj4 from 'proj4'
import {register} from 'ol/proj/proj4'
import {addCoordinateTransforms, addProjection, Projection, transform} from 'ol/proj'
import WMTSTileGrid from 'ol/tilegrid/WMTS'
import {defaults as defaultControls} from 'ol/control'
import {defaults as defaultInteractions} from 'ol/interaction'
import {Point} from "ol/geom";
import CircleStyle from "ol/style/Circle";

export default {
  props: {
    mapId: {
      type: String,
      default: "GDMap",
    },
    center: { // 地图默认显示的中心位置
      type: Array,
      default: () => [],
    },
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "100%",
    },
  },
  data(){
    return{
      GDMap: null,
      mapLoading: true,
    }
  },
  mounted() {
    this.source = new VectorSource({
      format: new GeoJSON(),
      loader: (extent) => {
        this.wfsLoad(extent)
        if (this.cityLayerFlag === true) {
          // this.layerList[4].layerObj.setZIndex(5)
          // this.customerLayerHandle(4, true)
          this.cityLayerFlag = false;
        }
      },
      strategy: bbox
    })

    this.editSource = new VectorSource()
    this.vector = new VectorLayer({
      source: this.source,
      zIndex: 4
    })

    this.markSource = new VectorSource()
    const styleCache = {};
    this.markLayer = new VectorLayer({
      source: new Cluster({
        distance: 30,
        minDistance: 5,
        source: this.markSource,
      }),
      style: function (feature) {
        const size = feature.get('features').length;
        let style = styleCache[size];
        if (!style) {
          style = new Style({
            image: new Icon({
              anchor: [0.5, 1],
              offset: [36, 22],
              size: [18, 26],
              src: require('@/assets/icons/map/ic_marker.png')
            })
          });
          styleCache[size] = style;
        }
        return style;
      },
    });

    // 注册4490坐标系
    proj4.defs("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs");
    register(proj4);
    const projection_4490 = new Projection({
      code: 'EPSG:4490',
      units: 'degrees',
      axisOrientation: 'neu'
    });
    projection_4490.setExtent([-180, -90, 180, 90])
    projection_4490.setWorldExtent([-180, -90, 180, 90])
    addProjection(projection_4490)
    addCoordinateTransforms('EPSG:4326', 'EPSG:4490',
      function (coordinate) {
        return proj4('EPSG:4326', 'EPSG:4490', coordinate)
      },
      function (coordinate) {
        return proj4('EPSG:4490', 'EPSG:4326', coordinate)
      }
    )

    let resolutions_4490 = [
      1.40625,
      0.703125,
      0.3515625,
      0.17578125,
      0.087890625,
      0.0439453125,
      0.02197265625,
      0.010986328125,
      0.0054931640625,
      0.00274658203125,
      0.001373291015625,
      6.866455078125e-4,
      3.4332275390625e-4,
      1.71661376953125e-4,
      8.58306884765625e-5,
      4.291534423828125e-5,
      2.1457672119140625e-5,
      1.0728836059570312e-5,
      5.364418029785156e-6,
      2.682209064925356e-6,
      1.3411045324626732e-6,
      6.705522662313365e-7,
    ]
    const fxpcSatelliteLayer = new TileLayer({
      source: new XYZ({
        url: 'https://fxpc.mem.gov.cn/data_preparation/a12eadf6-1a57-43fe-9054-2e22277bd553/4eb4b664-5633-4ab3-b0fd-345829dd3a87/wmts?layer=img&style=default&tileMatrixSet=c&service=wmts&request=gettile&version=1.0.0&format=tiles&tileMatrix={z}&tileCol={x}&tileRow={y}&geokey=2CA54B6D242305ABF3822EC38D121CD9',
        projection: projection_4490,
        maxZoom: 18,
        zIndex: 0
      })
    });
    // 自定义高精度卫星切片
    const custLayer = new TileLayer({
      source: new WMTS({
        url: 'https://map.dutkj.com/gwc/service/wmts',
        layer: 'dtsz:HONGJI',
        matrixSet: 'WebMercatorQuad',
        format: 'image/png',
        projection: 'EPSG:3857',
        tileGrid: new WMTSTileGrid({
          tileSize: [256, 256],
          extent: [-2.003750834E7, -2.0037508345578436E7, 2.0037508345578436E7, 2.003750834E7],
          origin: [-2.003750834E7, 2.003750834E7],
          resolutions: [156543.03392804076, 78271.51696402022, 39135.75848201011, 19567.879241005117, 9783.939620502542, 4891.969810251271, 2445.9849051256383, 1222.9924525628178, 611.4962262814075, 305.7481131407024, 152.8740565703523, 76.43702828517615, 38.21851414258808, 19.10925707129404, 9.55462853564699, 4.777314267823495, 2.388657133911756, 1.1943285669558765, 0.5971642834779383, 0.29858214173896913, 0.14929107086948457, 0.07464553543474216, 0.03732276771737108, 0.018661383858685567, 0.009330691929342784],
          matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']
        }),
        style: '',
        wrapX: true,
        zIndex: 1
      })
    });

    this.GDMap = new Map({
      target: this.mapId,
      controls: defaultControls({
        zoom: false
      }),
      layers: [
        fxpcSatelliteLayer,
        this.vector,
        this.markLayer
      ],
      view: new View({
        center: this.center.length ? transform(this.center, "EPSG:4326", "EPSG:4490") : transform([116.1733, 31.9137], "EPSG:4326", "EPSG:4490"),
        // center: this.center.length ? transform(this.center, "EPSG:4326", "EPSG:3857") : [13087853.731100908, 3652314.085522261],
        zoom: 14,
        resolutions: resolutions_4490,
        projection: projection_4490,
      }),
      interactions: new defaultInteractions({
        doubleClickZoom: false,   //屏蔽双击放大事件
      })
    })
    // 强制更新地图数据，防止部分情况初始化的时候地图被拉伸
    setTimeout(() => {
      this.GDMap.updateSize()
    }, 20)
    this.mapLoading = false
    this.initEvent()
    let sourceShowByZoom = false;

    this.GDMap.getView().on('change:resolution', () => {

      if (!this.contractSign) {
        if (this.GDMap.getView().getZoom() > 16) {
          if (this.useWfs && !sourceShowByZoom) {
            sourceShowByZoom = true
            this.source.clear(true)
            this.source.refresh()
          }
          this.vector.setVisible(true)
          if (this.markLayer) {
            this.markLayer.setVisible(false)
          }
        } else {
          sourceShowByZoom = false
          this.vector.setVisible(false)
          if (this.markLayer) {
            this.markLayer.setVisible(true)
          }
        }
        this.contractSign = false
      }
    });
  },
  computed: {
    loading() {
      return this.mapLoading
    },
  },
  methods:{
    wfsLoad(extent = '', callback) {
      if (!this.useWfs) {
        return false
      }
      const filter = this.getFilter()
      let option = {
        srsName: 'EPSG:4490',
        featureNS: 'http://www.opengeospatial.net/dtsz',
        featurePrefix: 'dtsz',
        // featureTypes: ['worldtest'],
        featureTypes: [this.wfsFeatureName],
        outputFormat: 'application/json',
        geometryName: 'shape',
      }
      if (filter != null) {
        option.filter = filter
      } else {
        if (this.GDMap.getView().getZoom() < 16) {
          return false
        }
        option.bbox = extent
      }
    },
    addPoint(point){
      let feature = new Feature({
        title: 'beijing',
        geometry: new Point([116.403218, 39.92372]),
      })
      feature.setStyle(
        new Style({
          image: new CircleStyle({
            fill: new Fill({
              color: 'blue',
            }),
            radius: 4,
          }),
        })
      );
      let source = new VectorSource()
      source.addFeature(feature)
      let layer = new VectorLayer()
      layer.setSource(source)
      map.addLayer(layer)
    }
  }
}

</script>
<style lang="scss" scoped>
.map {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  background-color: #f5f6f8;
  display: flex;

  .map-content {
    flex: 1;
    position: relative;
  }
}

</style>
